#pragma once

#include "glm/glm.hpp"
#include <string>
#include "Core/Core.h"
#include <unordered_map>


namespace Orange {
	class Shader
	{
	public:
		~Shader();
		
		  virtual void bind() = 0;
		  virtual void ubind() = 0;

		/// <summary>
		/// �ϴ� uniform ����
		/// </summary>
		
		  virtual void SetMat4(const std::string& name, const glm::mat4& mat) = 0;
		  virtual void SetFloat4(const std::string& name, const glm::vec4& mat) = 0;
		  virtual void SetFloat3(const std::string& name, const glm::vec3& mat) = 0;
		  virtual void SetInt(const std::string& name, const int value) = 0;
		  virtual void SetIntArray(const std::string& name, int* value, uint32_t count) = 0;
		  virtual void SetFloat(const std::string& name, const float value) = 0;
		  virtual void UploadUniformMat4f(const std::string& name, const glm::mat4& mat) = 0;
		  virtual void UploadUniform4f(const std::string& name, const glm::vec4& mat) = 0;
		  virtual void UploadUniform3f(const std::string& name, const glm::vec3& mat) = 0;
		  virtual void UploadUniform2f(const std::string& name, const glm::vec2& mat) = 0;
		  virtual void UploadUniform1f(const std::string& name, const float value) = 0;
		  virtual void UploadUniformInt(const std::string& name, const int value) = 0;

		
		  static Ref<Shader> Create(const std::string& filepath);
		  static Ref<Shader> Create(const std::string& name, const std::string& vertexShaderSrc, const std::string& fragmentShaderSrc);
		

		  virtual const std::string& GetName() const = 0;
	};

	class ShaderLibrary {
	public:
		void Add(const Ref<Shader>& shader);
		void Add(const std::string& name, const Ref<Shader>& shader);
		Ref<Shader> Load(const std::string& filepath);
		Ref<Shader> Load(const std::string& name, const std::string& filepath);
		Ref<Shader> Get(const std::string& name);

	private:
		std::unordered_map<std::string, Ref<Shader>> m_Shaders;
	};
	
}